package com.zhuo.project.order.controller;

import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zhuo.common.constant.RedisKeyConstants;
import com.zhuo.common.enums.AuditStatus;
import com.zhuo.common.enums.IsAudit;
import com.zhuo.common.utils.SecurityUtils;
import com.zhuo.common.utils.StringUtils;
import com.zhuo.framework.aspectj.lang.annotation.Log;
import com.zhuo.framework.aspectj.lang.enums.BusinessType;
import com.zhuo.framework.redis.RedisCache;
import com.zhuo.framework.security.LoginUser;
import com.zhuo.framework.web.domain.TreeSelect;
import com.zhuo.project.k3.domain.ZzMaterialBarcode;
import com.zhuo.project.k3.service.IZzMaterialBarcodeService;
import com.zhuo.project.order.domain.ZzDiagnoseHead;
import com.zhuo.project.order.domain.ZzDiagnoseHeadAuditDto;
import com.zhuo.project.order.domain.ZzDiagnoseHeadDto;
import com.zhuo.project.order.service.IZzDiagnoseHeadService;
import com.zhuo.framework.web.controller.BaseController;
import com.zhuo.framework.web.domain.AjaxResult;
import com.zhuo.common.utils.poi.ExcelUtil;
import com.zhuo.framework.web.page.TableDataInfo;
import com.zhuo.project.system.domain.SysDept;
import com.zhuo.project.system.domain.SysUser;
import com.zhuo.project.system.service.ISysDeptService;
import com.zhuo.project.system.service.ISysUserService;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;

/**
 * 处方单Controller
 *
 * @author zhuo
 * @date 2020-03-22
 */
@Api("订单操作")
@RestController
@RequestMapping("/order/head")
public class ZzDiagnoseHeadController extends BaseController {
    @Autowired
    private IZzDiagnoseHeadService zzDiagnoseHeadService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private ISysDeptService deptService;

    /**
     * 查询处方单列表
     */
    @ApiOperation("获取处方列表")
    @ApiImplicitParam(name = "zzDiagnoseHeadDto", value = "获取处方列表", dataType = "ZzDiagnoseHeadDto")
    @PreAuthorize("@ss.hasPermi('order:head:list')")
    @GetMapping("/list")
    public TableDataInfo list(ZzDiagnoseHeadDto zzDiagnoseHeadDto) {
        logger.info("请求参数{}", JSONUtil.toJsonPrettyStr(zzDiagnoseHeadDto));
        String deptIds = zzDiagnoseHeadDto.getDeptIds();
        List<String> deptList = new ArrayList<>();
        if (StrUtil.isBlank(deptIds)) {
            Long deptId = SecurityUtils.getLoginUser().getUser().getDeptId();
            SysDept sysDeptSelect = deptService.selectDeptById(deptId);
            String deptCode = sysDeptSelect.getDeptCode();
            List<SysDept> deptSelect = deptService.buildChildDeptListByDeptCode(deptCode);
            deptList = deptSelect.stream().filter(sysDept -> StrUtil.isNotEmpty(sysDept.getDeptCode()))
                    .map(SysDept::getDeptCode).collect(Collectors.toList());
        } else {
            String[] deptIdList = deptIds.split(",");
            for (String deptId : deptIdList) {
                SysDept sysDeptSelect = deptService.selectDeptById(Long.parseLong(deptId));
                String deptCode = sysDeptSelect.getDeptCode();
                if (StrUtil.isNotBlank(deptCode)) {
                    deptList.add(deptCode);
                }
            }
        }

        if (StrUtil.isNotBlank(zzDiagnoseHeadDto.getAuditStatusStr())) {
            String[] auditStatusStrList = zzDiagnoseHeadDto.getAuditStatusStr().split(",");
            List<Integer> auditStatusList = new ArrayList<>(auditStatusStrList.length);
            for (String auditStatus : auditStatusStrList) {
                auditStatusList.add(Integer.parseInt(auditStatus));
            }
            zzDiagnoseHeadDto.setAuditStatusList(auditStatusList);
        }

        if (StrUtil.isNotBlank(zzDiagnoseHeadDto.getIsEquipStr())) {
            String[] isEquipStrList = zzDiagnoseHeadDto.getIsEquipStr().split(",");
            List<Integer> isEquipList = new ArrayList<>(isEquipStrList.length);
            for (String isEquip : isEquipStrList) {
                isEquipList.add(Integer.parseInt(isEquip));
            }
            zzDiagnoseHeadDto.setIsEquipList(isEquipList);
        }

        if (StrUtil.isNotBlank(zzDiagnoseHeadDto.getIsSendStr())) {
            String[] isSendStrList = zzDiagnoseHeadDto.getIsSendStr().split(",");
            List<Integer> isSendList = new ArrayList<>(isSendStrList.length);
            for (String isSend : isSendStrList) {
                isSendList.add(Integer.parseInt(isSend));
            }
            zzDiagnoseHeadDto.setIsSendList(isSendList);
        }

        if (StrUtil.isNotBlank(zzDiagnoseHeadDto.getIsBillStr())) {
            String[] isBillStrList = zzDiagnoseHeadDto.getIsBillStr().split(",");
            List<Integer> isBillList = new ArrayList<>(isBillStrList.length);
            for (String isBill : isBillStrList) {
                isBillList.add(Integer.parseInt(isBill));
            }
            zzDiagnoseHeadDto.setIsBillList(isBillList);
        }
        zzDiagnoseHeadDto.setDepts(deptList);
        zzDiagnoseHeadDto.setOrderType(1);
        startPage();
        List<ZzDiagnoseHead> list = zzDiagnoseHeadService.selectZzDiagnoseHeadList(zzDiagnoseHeadDto);
        return getDataTable(list);
    }

    /**
     * 导出处方单列表
     */
    @ApiOperation("导出处方")
    @ApiImplicitParam(name = "zzDiagnoseHeadDto", value = "导出处方", dataType = "ZzDiagnoseHeadDto")
    @PreAuthorize("@ss.hasPermi('order:head:export')")
    @Log(title = "处方单", businessType = BusinessType.EXPORT)
    @GetMapping("/export")
    public AjaxResult export(ZzDiagnoseHeadDto zzDiagnoseHeadDto) {
        String deptCode = zzDiagnoseHeadDto.getDeptCode();
        List<SysDept> deptSelect = deptService.buildChildDeptListByDeptCode(deptCode);
        List<String> deptList = deptSelect.stream().filter(sysDept -> StrUtil.isNotEmpty(sysDept.getDeptCode()))
                .map(SysDept::getDeptCode).collect(Collectors.toList());
        zzDiagnoseHeadDto.setDepts(deptList);
        zzDiagnoseHeadDto.setOrderType(1);
        List<ZzDiagnoseHead> list = zzDiagnoseHeadService.selectZzDiagnoseHeadList(zzDiagnoseHeadDto);
        ExcelUtil<ZzDiagnoseHead> util = new ExcelUtil<ZzDiagnoseHead>(ZzDiagnoseHead.class);
        return util.exportExcel(list, "head");
    }

    /**
     * 获取处方单详细信息
     */
    @ApiOperation("获取处方明细")
    @ApiImplicitParam(name = "id", value = "id", required = true, dataType = "Long", paramType = "path")
    @PreAuthorize("@ss.hasPermi('order:head:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id) {
        return AjaxResult.success(zzDiagnoseHeadService.selectZzDiagnoseHeadById(id));
    }

    /**
     * 审核处方单
     */
    @ApiOperation("审核处方")
    @ApiImplicitParam(name = "zzDiagnoseHeadAuditDto", value = "审核处方", dataType = "ZzDiagnoseHeadAuditDto")
    @PreAuthorize("@ss.hasPermi('order:head:edit')")
    @Log(title = "处方单", businessType = BusinessType.UPDATE)
    @PostMapping(value = "/audit")
    public AjaxResult audit(@RequestBody ZzDiagnoseHeadAuditDto zzDiagnoseHeadAuditDto) {
        ZzDiagnoseHead zzDiagnoseHeadDb =
                zzDiagnoseHeadService.selectZzDiagnoseHeadById(zzDiagnoseHeadAuditDto.getId());
        if (!zzDiagnoseHeadDb.getAuditStatus().equals(AuditStatus.UNAUDIT.getCode()) && !zzDiagnoseHeadDb
                .getAuditStatus().equals(AuditStatus.REAUDIT.getCode())) {
            AjaxResult.error(3014, "处方审核状态已审核");
        }
        ZzDiagnoseHead zzDiagnoseHead = new ZzDiagnoseHead();
        zzDiagnoseHead.setId(zzDiagnoseHeadAuditDto.getId());
        LoginUser loginUser = SecurityUtils.getLoginUser();
        zzDiagnoseHead.setAuditorId(SecurityUtils.getUsername());
        zzDiagnoseHead.setAuditorName(loginUser.getUser().getNickName());
        zzDiagnoseHead.setAuditorTime(new Date());
        Integer isAudit = IsAudit.NEED.getCode();
        if (zzDiagnoseHeadAuditDto.getAuditStatus() == 4) {
            isAudit = IsAudit.UNNEED.getCode();
        }
        zzDiagnoseHead.setIsAudit(isAudit);
        zzDiagnoseHead.setAuditStatus(zzDiagnoseHeadAuditDto.getAuditStatus());
        zzDiagnoseHead.setAuditContent(zzDiagnoseHeadAuditDto.getAuditContent());
        return toAjax(zzDiagnoseHeadService.updateZzDiagnoseHead(zzDiagnoseHead));
    }


    /**
     * 新增处方单
     */
    @PreAuthorize("@ss.hasPermi('order:head:add')")
    @Log(title = "处方单", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody ZzDiagnoseHead zzDiagnoseHead) {
        return toAjax(zzDiagnoseHeadService.insertZzDiagnoseHead(zzDiagnoseHead));
    }

    /**
     * 保存查询条件
     */
    @ApiOperation("保存处方查询条件")
    @ApiImplicitParam(name = "zzDiagnoseHeadDto", value = "保存查询条件", dataType = "ZzDiagnoseHeadDto")
    @PreAuthorize("@ss.hasPermi('order:head:list')")
    @Log(title = "处方单", businessType = BusinessType.INSERT)
    @PostMapping(value = "/addQueryParam")
    public AjaxResult addQueryParam(@RequestBody ZzDiagnoseHeadDto zzDiagnoseHeadDto) {
        String userName = SecurityUtils.getUsername();
        String userQueryKey = MessageFormat
                .format(RedisKeyConstants.DIAGNOSE_QUERY_PARAM_KEY, userName);
        logger.info("请求参数：" + JSON.toJSONString(zzDiagnoseHeadDto));
        redisCache.setCacheObject(userQueryKey, JSON.toJSONString(zzDiagnoseHeadDto));
        return toAjax(1);
    }


    @ApiOperation("获取下一条待审处方id")
    @PreAuthorize("@ss.hasPermi('order:head:list')")
    @GetMapping(value = "/getAuditOne/{id}")
    public AjaxResult getAuditOne(@PathVariable("id") Long id) {
        String userName = SecurityUtils.getUsername();
        String userQueryKey = MessageFormat
                .format(RedisKeyConstants.DIAGNOSE_QUERY_PARAM_KEY, userName);
        ZzDiagnoseHeadDto zzDiagnoseHeadDto = new ZzDiagnoseHeadDto();
        if (redisCache.hasKey(userQueryKey)) {
            String queryParam = redisCache.getCacheObject(userQueryKey);
            ZzDiagnoseHeadDto zzDiagnoseHeadDtoCache = JSONUtil.toBean(queryParam, ZzDiagnoseHeadDto.class);
            zzDiagnoseHeadDto.setDeptIds(zzDiagnoseHeadDtoCache.getDeptIds());
        }
        String deptIds = zzDiagnoseHeadDto.getDeptIds();
        List<String> deptList = new ArrayList<>();
        if (StrUtil.isBlank(deptIds)) {
            Long deptId = SecurityUtils.getLoginUser().getUser().getDeptId();
            SysDept sysDeptSelect = deptService.selectDeptById(deptId);
            String deptCode = sysDeptSelect.getDeptCode();
            List<SysDept> deptSelect = deptService.buildChildDeptListByDeptCode(deptCode);
            deptList = deptSelect.stream().filter(sysDept -> StrUtil.isNotEmpty(sysDept.getDeptCode()))
                    .map(SysDept::getDeptCode).collect(Collectors.toList());
        } else {
            String[] deptIdList = deptIds.split(",");
            for (String deptId : deptIdList) {
                SysDept sysDeptSelect = deptService.selectDeptById(Long.parseLong(deptId));
                String deptCode = sysDeptSelect.getDeptCode();
                if (StrUtil.isNotBlank(deptCode)) {
                    deptList.add(deptCode);
                }
            }
        }

        zzDiagnoseHeadDto.setDepts(deptList);
        zzDiagnoseHeadDto.setAuditStatus(AuditStatus.UNAUDIT.getCode());
        List<ZzDiagnoseHead> unAuditList = zzDiagnoseHeadService.selectZzDiagnoseHeadList(zzDiagnoseHeadDto);

        // 查询出重新审核的单子
        zzDiagnoseHeadDto.setAuditStatus(AuditStatus.REAUDIT.getCode());
        List<ZzDiagnoseHead> reAuditList = zzDiagnoseHeadService.selectZzDiagnoseHeadList(zzDiagnoseHeadDto);

        List<ZzDiagnoseHead> list = new ArrayList<>();
        list.addAll(unAuditList);
        list.addAll(reAuditList);
        list.sort(new Comparator<ZzDiagnoseHead>() {
                      @Override
                      public int compare(ZzDiagnoseHead o1, ZzDiagnoseHead o2) {
                          return DateUtil.compare(o1.getDiagnoseCreatedAt(), o2.getDiagnoseCreatedAt());
                      }
                  }
        );


        ZzDiagnoseHead current = zzDiagnoseHeadService.selectZzDiagnoseHeadById(id);
        if (list.size() > 0) {
            Long retId = -1L;
            for (ZzDiagnoseHead zzDiagnoseHead : list) {
                if (DateUtil.compare(zzDiagnoseHead.getDiagnoseCreatedAt(), current.getDiagnoseCreatedAt()) >= 0
                        && zzDiagnoseHead.getId().compareTo(id) != 0) {
                    retId = zzDiagnoseHead.getId();
                    break;
                }
            }
            if (retId > 0) {
                return AjaxResult.success(retId);
            } else {
                return AjaxResult.error(3020, "没有下一条待审核处方，请从头开始审核");
            }

        } else {
            return AjaxResult.error(3002, "没有待审核处方");
        }
    }

    /**
     * 获取处方单查询条件
     */
    @ApiOperation("查询处方查询条件")
    @PreAuthorize("@ss.hasPermi('order:head:list')")
    @GetMapping(value = "/getQueryParam")
    public AjaxResult getQueryInfo() {
        String userName = SecurityUtils.getUsername();
        String userQueryKey = MessageFormat
                .format(RedisKeyConstants.DIAGNOSE_QUERY_PARAM_KEY, userName);
        String queryParam = redisCache.getCacheObject(userQueryKey);
        ZzDiagnoseHeadDto zzDiagnoseHeadDto = JSONUtil.toBean(queryParam, ZzDiagnoseHeadDto.class);
        return AjaxResult.success(zzDiagnoseHeadDto);
    }


    /**
     * 修改处方单
     */
    @PreAuthorize("@ss.hasPermi('order:head:edit')")
    @Log(title = "处方单", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody ZzDiagnoseHead zzDiagnoseHead) {
        return toAjax(zzDiagnoseHeadService.updateZzDiagnoseHead(zzDiagnoseHead));
    }

    /**
     * 删除处方单
     */
    @PreAuthorize("@ss.hasPermi('order:head:remove')")
    @Log(title = "处方单", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids) {
        return toAjax(zzDiagnoseHeadService.deleteZzDiagnoseHeadByIds(ids));
    }
}
